package com.dingding.special.user.set.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.ICriteriaBaseDao;
import com.dingding.common.core.base.dto.AbstractValiResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.UserTaxiOrdert;
import com.dingding.common.core.beans.special.SpecialOrderdesignateset;
import com.dingding.common.core.beans.special.Specialuserposition;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.bean.BeanUtilx;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.facade.special.trasfer.up_posi.ReqSetUserStatusDTO;
import com.dingding.special.user.enums.userInfo.OutwardRunStatus;
import com.dingding.special.user.set.dao.ISetUserStatusDao;
import com.dingding.special.user.set.dto.ReqOrderDesignateSetDTO;
import com.dingding.special.user.set.enums.OperationTypeEnum;
import com.dingding.special.user.set.message.SetUserStatusMessage;
import com.dingding.special.user.set.service.ISetUserStatusService;

/**
 * 
 * @ClassName: OutwardRun 
 * @Description: 设置用户状态（出车收车）
 * @author CHEHAUNBO 
 * @date 2016年8月18日 上午11:12:54
 * @since V2.4.0
 * 
 */
@Component("setUserStatusService")
public class SetUserStatusServiceImpl extends AbstractValiResponse implements ISetUserStatusService {

	@Resource(name = "setUserStatusDao")
	private ISetUserStatusDao setUserStatusDao;

	@Resource(name = "criteriaBaseDao")
	private ICriteriaBaseDao criteriaBaseDao;

	private static final Logger log = Logger.getLogger(SetUserStatusServiceImpl.class);

	/**
	 * 
	 * 用户操作调度类 
	 * 
	 * 出车 收车 上传车辆位置
	 * 
	 * 
	 * @Title: setDriverStatus 
	 * @param reqSetUserStatusDTO
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public ResponseEntity<Object> setDriverStatus(ReqSetUserStatusDTO reqSetUserStatusDTO) {
		try {

			ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqSetUserStatusDTO,
					ReqSetUserStatusDTO.class);

			if (!valiResult.isAvailable()) {
				return super.error(valiResult);
			}

			Criterion criterion = Restrictions.eq("userId", reqSetUserStatusDTO.getUserId());
			Specialuserposition specialuserposition = criteriaBaseDao.queryCriteriaListUnique(Specialuserposition.class,
					criterion);

			if (specialuserposition == null) {
				specialuserposition = new Specialuserposition();
				specialuserposition.setSupId(ToolUtil.getUid());
				specialuserposition.setUserId(reqSetUserStatusDTO.getUserId());
				specialuserposition.setOnlineDuration(new BigDecimal(0));
			}

			// 更新用户位置信息
			specialuserposition.setCurrentCity(reqSetUserStatusDTO.getCurrentCity()); // 当前城市
			specialuserposition.setLongitude(reqSetUserStatusDTO.getLongitude()); // 经度
			specialuserposition.setLatitude(reqSetUserStatusDTO.getLatitude()); // 纬度
			if (reqSetUserStatusDTO.getOperationType() != OperationTypeEnum.UploadPosition.getValue()) { // 上传位置
				if (reqSetUserStatusDTO.getOperationType() == OperationTypeEnum.OutWard.getValue()) { // 出车
					if (specialuserposition.getOutwardRunTime() != null) {
						if (!DateUtils.isSameDay(specialuserposition.getOutwardRunTime(), new Date())) {
							specialuserposition.setOnlineDuration(new BigDecimal(0));
						}
					}
					specialuserposition.setOutwardRunTime(new Date()); // 出车时间
					specialuserposition.setSupStatus(OutwardRunStatus.outWardRun.getValue());// 出车状态
				} else if (reqSetUserStatusDTO.getOperationType() == OperationTypeEnum.CloseCar.getValue()) { // 收车
					// 获取是否存在进行中订单
					Criterion order_crition = Restrictions.and(
							Restrictions.eq("grabOrderUserId", reqSetUserStatusDTO.getUserId()),
							Restrictions.or(Restrictions.eq("orderStatus", 2),Restrictions.eq("orderStatus", 3)));
					
					// 专车进行中订单列表
					List<UserspecialorderT> userspecialorderTs = criteriaBaseDao.queryCriteriaList(UserspecialorderT.class, order_crition);
					// 出租车进行中订单列表
					List<UserTaxiOrdert> userTaxiOrderts = criteriaBaseDao.queryCriteriaList(UserTaxiOrdert.class, order_crition);
					
					
					if ((userspecialorderTs != null && userspecialorderTs.size() > 0) || (userTaxiOrderts != null && userTaxiOrderts.size() > 0)) {
						return super.error(HttpStatus.SC_FORBIDDEN, SetUserStatusMessage.APP_ERROR,
								SetUserStatusMessage.EXISIS_ORDER);
					} else {
						specialuserposition.setOnlineDuration(setOnlineDuration(new Date(),
								specialuserposition.getOutwardRunTime(), specialuserposition.getOnlineDuration()));
						specialuserposition.setSupStatus(OutwardRunStatus.close.getValue());
					}

				}
			}

			// 更新用户实时位置信息
			setUserStatusDao.updateSpecialDriverPosition(specialuserposition, reqSetUserStatusDTO.getOperationType());
			if (reqSetUserStatusDTO.getOperationType() != OperationTypeEnum.UploadPosition.getValue()) {
				// 新添加用户出车记录信息
				setUserStatusDao.saveOutwardRunRecord(specialuserposition, reqSetUserStatusDTO.getOperationType());
			}

			return success(HttpStatus.SC_OK);

		} catch (Exception e) {
			log.error("一键收车出现异常！", e);
			return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, SetUserStatusMessage.ADD_DRIVERPOSITION_TO_CACHE_ERROR,
					SetUserStatusMessage.SERVER_ERROR);
		}
	}

	/**
	 * 
	 * 设置在线时长
	 * 
	 * @Title: setOnlineDuration
	 * @param specialuserposition 用户位置信息
	 * @param closeCarTimeDate 本次收车时间
	 * @param outwardRunTime 出车时间
	 * @param onlineDuration 上一次的在线时长
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private BigDecimal setOnlineDuration(Date closeCarTimeDate, Date outwardRunTime, BigDecimal onlineDuration) {

		// 2 计算本次出车阶段的在线时长
		Date currentTime = new Date();
		Double duration = DateFormatUtil.dateHH(currentTime, outwardRunTime);
		return onlineDuration.add(new BigDecimal(duration));

	}

	/**
	 * 
	 * 偏好设置 
	 * 
	 * @Title: setOrderDesignateSet 
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public ResponseEntity<Object> setOrderDesignateSet(ReqOrderDesignateSetDTO reqOrderDesignateSetDTO) {

		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqOrderDesignateSetDTO,
				ReqOrderDesignateSetDTO.class);

		if (!valiResult.isAvailable()) {
			return super.error(valiResult);
		}

		// 获取用户偏好设置信息
		try {

			Criterion criterion = Restrictions.eq("userId", reqOrderDesignateSetDTO.getUserId());

			SpecialOrderdesignateset orderdesignateset = criteriaBaseDao
					.queryCriteriaListUnique(SpecialOrderdesignateset.class, criterion);

			if (orderdesignateset != null) {
				BeanUtilx.copyProperties(orderdesignateset, reqOrderDesignateSetDTO);
				orderdesignateset
						.setStartTime(DateFormatUtil.yyyy_MM_dd_HHmm_CN(reqOrderDesignateSetDTO.getStartTime()));
				orderdesignateset.setEndTime(DateFormatUtil.yyyy_MM_dd_HHmm_CN(reqOrderDesignateSetDTO.getEndTime()));
				return super.success(HttpStatus.SC_OK);
			}

			return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, SetUserStatusMessage.USER_NOT_EXIST,
					SetUserStatusMessage.APP_ERROR);

		} catch (Exception e) {
			log.error("设置用户偏好位置出现异常！", e);
		}

		return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, SetUserStatusMessage.SET_USERPOSITION_ERROR,
				SetUserStatusMessage.SERVER_ERROR);

	}

}
